import { Utils } from '../utils/utils.js';
import { BaseControl } from './BaseControl.js';
import { FormControl } from './FormControl.js';
import { FormGroup } from './FormGroup.js';
// import { ArrayError } from './form.interface';



export class FormArray extends BaseControl {
	constructor(formItems) {
		super();
		if (Utils.isArray(formItems) && formItems.length > 0) {
			formItems.forEach((formItem) => {
				this.push(formItem);
			});
		}
	}

	/**
	 * @description FormGroup包含的FormControl | FormArray | FormGroup  只读
	 */
	_controls = [];
	get controls() {
		return this.getControls();
	}
	getControls = () => {
		return this._controls;
	}
	/**
	 * @description 向FormArray中push FormControl | FormArray | FormGroup
	 * @param {FormControl | FormArray | FormGroup} formItem
	 */
	push = (formItem) => {
		formItem.parent = this;
		this._controls.push(formItem);
		this.onCollectionChange();
		this._updateControls();
		return this;
	};
	del = (index) => {
		if (index > -1) {
			this._controls.splice(index, 1);
		}
		this.onCollectionChange();
		this._updateControls();
		return this;
	};
	clear = () => {
		this._controls = [];
		this.onCollectionChange();
		this._updateControls();
		return this;
	};
	at = (index) => {
		return this._controls[index];
	};
	concat = (formArray) => {
		const isFormArray = formArray instanceof FormArray;
		if (isFormArray) {
			formArray.controls.forEach(formItem => {
				this._controls.push(formItem);
			});
			this.onCollectionChange();
		}
		this._updateControls();
		return this._controls;
	};
	/**  this._controls 返回一个新数组 */
	_updateControls = () => {
		this._controls = this._controls.concat([]);
		this._controls.forEach(formItem => {
			formItem.update();
		});
		this.onCollectionChange();
		return this._controls;
	};
	/** 跟新内部数据 */
	update = () => {
		this._updateControls()
	};
	/**
	 * @description FormArray的值。
	 */
	_value = [];
	get value() {
		this._updateValue();
		return [...this._value];
	}
	/**
	 * @description 更新FormArray的value
	 */
	_updateValue = () => {
		const result = [];
		for (const formItem of this._controls) {
			const value = formItem.value;
			result.push(value);
		}
		this._value = result;
		this.runValueChangeCallbacks(this._value);
		return this._value;
	};
	/**
	 * @description FormArray的脏值。
	 */
	_dirtyValue = [];
	get dirtyValue() {
		this._updateDirtyValue();
		return [...this._dirtyValue];
	}
	_updateDirtyValue = () => {
		// 上次结果
		// const provDirty = this._dirty;
		this._dirtyValue = [];
		for (const formItem of this._controls) {
			const dirty = formItem.dirty;
			const value = formItem.value;
			if (dirty === true) {
				this._dirtyValue.push(value);
			}
		}
	};
	/**
	 * @description 验证结果 只读 boolean
	 */
	_valid = true;
	get valid() {
		this._updateValid();
		return this._valid;
	}
	_updateValid = () => {
		const errors = [];
		// 上次验证结果
		const provValid = this._valid;
		this._valid = true;
		// for (const formItem of this._controls) {
		// 	const valid = formItem.valid;
		// 	if (valid === false) {
		// 		this._valid = false;
		// 	}
		// }
		for (let i = 0; i < this._controls.length; i++) {
			const formItem = this._controls[i];
			const valid = formItem.valid;
			if (valid === false) {
				this._valid = false;
				errors.push({ errorIndex: i, errorItem: formItem });
			}
		}
		this._errors = errors;
		if (provValid !== this._valid) {
			this.runValidChangeCallbacks(this._valid);
		}
	};
	/**
	 * @description 脏值 只读 boolean
	 */
	_dirty = false;
	get dirty() {
		this._updateDirty();
		return this._dirty;
	}
	_updateDirty = () => {
		// 上次结果
		const provDirty = this._dirty;
		this._dirty = false;
		for (const formItem of this._controls) {
			const dirty = formItem.dirty;
			if (dirty === true) {
				this._dirty = true;
			}
		}
		// 是否发生改变
		const isChanged = provDirty !== this._dirty;
		if (isChanged) {
			this.runDirtyChangeCallbacks(this._dirty);
		}
	};

	/** 设置只读 */
	set readonly(val) {
		for (const key in this._controls) {
			const formItem = this._controls[key];
			if (formItem.readonlyException === false) {
				formItem.readonly = val;
			}
		}
	};

	/**
	 * @description 重置
	 */
	reset = () => {
		for (const formItem of this._controls) {
			formItem.reset();
		}
	};

	/**
	 * @description 当内部元素发生改变时。
	 */
	onCollectionChange = () => {
		this._updateValue();
		this._updateValid();
		this._updateDirty();
		if (this.parent) {
			this.parent.onCollectionChange();
		}
	};

	/** 自定义提交表单前验证 */
	beforeSubmit = () => true;

	_errors = [];
	get errors() {
		return this._errors;
	}
	/** formArray 的数据 */
	arrayData = {};

}
